package org.ktx.osr.widget

import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.ViewConfiguration
import android.view.WindowManager
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.core.view.isVisible
import org.ktx.osr.MainActivity
import org.ktx.osr.R
import org.ktx.osr.service.ScreenRecordingService
import kotlin.math.abs

@SuppressLint("ClickableViewAccessibility")
class FloatingControlWidget @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {

    private val root = LayoutInflater.from(context).inflate(R.layout.floating_widget, this, true)
    private val playView: ImageView = root.findViewById(R.id.play)
    private val stopView: ImageView = root.findViewById(R.id.stop)
    private val settingsView: ImageView = root.findViewById(R.id.settings)
    private val durationView: TextView = root.findViewById(R.id.tv_duration)
    private val recordingView: ImageView = root.findViewById(R.id.iv_rec)
    private val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
    private val touchSlop = ViewConfiguration.get(context).scaledTouchSlop
    private var lastX: Float = 0f
    private var lastY: Float = 0f
    private var firstX: Int = 0
    private var firstY: Int = 0
    private var isDragging = false
    private var animator: ValueAnimator? = null

    init {
        settingsView.setOnClickListener { gotoSettings() }
        updateRecordingState(ScreenRecordingService.STATE_STOPPED)
        setOnTouchListener { _, event ->
            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    lastX = event.rawX
                    lastY = event.rawY
                    firstX = (layoutParams as WindowManager.LayoutParams).x
                    firstY = (layoutParams as WindowManager.LayoutParams).y
                    isDragging = false
                }

                MotionEvent.ACTION_MOVE -> {
                    val dx = event.rawX - lastX
                    val dy = event.rawY - lastY
                    if (abs(dx) > touchSlop || abs(dy) > touchSlop) {
                        isDragging = true
                    }
                    if (isDragging) {
                        val params = layoutParams as WindowManager.LayoutParams
                        params.x = firstX + (event.rawX - lastX).toInt()
                        params.y = firstY + (event.rawY - lastY).toInt()
                        wm.updateViewLayout(this, params)
                    }
                }

                MotionEvent.ACTION_UP -> {
                    if (!isDragging) {
                        performClick()
                    }
                }
            }
            true
        }
    }

    private fun gotoSettings() {
        val intent = Intent(context, MainActivity::class.java)
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP)
        context.startActivity(intent)
    }

    fun setOnToggleRecordingListener(listener: OnClickListener) {
        playView.setOnClickListener(listener)
    }

    fun setOnStopListener(listener: OnClickListener) {
        stopView.setOnClickListener(listener)
    }

    fun setRecordingDuration(duration: String) {
        durationView.text = duration
    }

    fun updateRecordingState(state: Int) {
        when (state) {
            ScreenRecordingService.STATE_RECORDING -> {
                playView.setImageResource(R.drawable.ic_pause)
                stopView.isVisible = true
                animator = ValueAnimator.ofFloat(0.2F, 1F).apply {
                    duration = 1000
                    repeatMode = ValueAnimator.REVERSE
                    repeatCount = ValueAnimator.INFINITE
                    addUpdateListener {
                        val value = it.animatedValue as Float
                        recordingView.alpha = value
                    }
                    start()
                }
            }
            ScreenRecordingService.STATE_PAUSED -> {
                playView.setImageResource(R.drawable.ic_play)
                stopView.isVisible = true
                animator?.end()
            }
            else -> {
                playView.setImageResource(R.drawable.ic_play)
                stopView.isVisible = false
                animator?.end()
            }
        }
    }
}
